﻿using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinAction.Action
{
	public static class KeyboardAction
	{
		/// <summary>
		/// 键盘模拟事件
		/// </summary>
		/// <param name="bVk">键盘码</param>
		/// <param name="bScan">0</param>
		/// <param name="dwFlags">0->按下，2->松开</param>
		/// <param name="dwExtraInfo">0</param>
		[DllImport("user32.dll", SetLastError = true)]
		private static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo);

		/// <summary>
		/// 获取键盘码对应的扫描码
		/// </summary>
		/// <param name="nCode">键盘码/扫描码</param>
		/// <param name="uMapType">0->将键盘吗->扫描码</param>
		/// <returns></returns>
		[DllImport("user32.dll")]
		private static extern uint MapVirtualKey(uint nCode, uint uMapType);


		/// <summary>
		/// 向激活的窗口上发生一段文本
		/// </summary>
		/// <param name="text">文本内容</param>
		/// <param name="delay">发送延时/默认0ms</param>
		public static async void SendText(string text, int delay = 0)
		{
			await Task.Delay(delay);
			SendKeys.SendWait(text);
		}

		/// <summary>
		/// 按下一个键
		/// </summary>
		/// <param name="key">待按下的键</param>
		public static void PressKey(Keys key)
		{
			uint keyCode = (uint)key;
			byte nScan = (byte)MapVirtualKey(keyCode, 0);
			keybd_event(0, nScan, 8, 0);
		}

		/// <summary>
		/// 松开一个已经按下的键
		/// </summary>
		/// <param name="key">待松开的键</param>
		public static void ReleaseKey(Keys key)
		{
			uint keyCode = (uint)key;
			byte nScan = (byte)MapVirtualKey(keyCode, 0);
			keybd_event(0, nScan, 8 | 2, 0);
		}

		/// <summary>
		/// 按下某一个键
		/// </summary>
		/// <param name="key">键码</param>
		/// <param name="times">次数/默认一次</param>
		/// <param name="delay">多次按下的延时</param>
		public static async void PressKeyExt(Keys key, int times = 1, int delay = 0)
		{
			uint keyCode = (uint)key;
			byte nScan = (byte)MapVirtualKey(keyCode, 0);
			for (int i = 0; i < times; i++)
			{
				keybd_event(0, nScan, 8, 0);
				await Task.Delay(delay);
				keybd_event(0, nScan, 8 | 2, 0);
			}
		}


		/// <summary>
		/// 长按某一个键
		/// </summary>
		/// <param name="key">键码</param>
		/// <param name="time">时间ms/默认5秒</param>
		public static async void ProcessLongKey(Keys key, int time = 5000)
		{
			uint keyCode = (uint)key;
			byte nScan = (byte)MapVirtualKey(keyCode, 0);
			keybd_event(0, nScan, 8, 0);
			await Task.Delay(time);
			keybd_event(0, nScan, 8 | 2, 0);
		}


		/// <summary>
		/// 发送组合键
		/// </summary>
		/// <param name="keys">键码数组</param>
		public static void PressMulKey(params Keys[] keys)
		{
			foreach (var key in keys)
			{
				uint keyCode = (uint)key;
				byte nScan = (byte)MapVirtualKey(keyCode, 0);
				keybd_event(0, nScan, 8, 0);
			}
			foreach (var key in keys)
			{
				uint keyCode = (uint)key;
				byte nScan = (byte)MapVirtualKey(keyCode, 0);
				keybd_event(0, nScan, 8 | 2, 0);
			}
		}


	}
}
